﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine;

public class TextureOptimize
{
    /// <summary>
    /// 压缩png图片到设置的MaxSize大小
    /// </summary>
    [MenuItem("Tools/Zhan/Compressed Pictures to MaxSize in Setting")]
    public static void CompressedArtPicturestoSettingMaxSize()
    {
        //string picturesDir = Path.Combine(Application.dataPath, "data");// "ArtAssets\\AC_ArtAssets\\Character\\Models\\1220\\Common\\tongyongyanjing_01");

        ScalePngFiles();
    }
    //static List<string> GetFiles(string dir,params string[] extensions)
    //{
    //    string[] files = Directory.GetFiles(dir);

    //    List<string> matchFiles = new List<string>();

    //    foreach (string file in files)
    //    {
    //        foreach (var extension in extensions)
    //        {
    //            string lower = extension.ToLower();
    //            if (Path.GetExtension(file).ToLower().Equals(lower, StringComparison.OrdinalIgnoreCase))
    //            {
    //                matchFiles.Add(file);
    //            }
    //        }
    //    }
    //    return matchFiles;
    //}
    static void ScalePngFiles()
    {
        List<string> pngFiles = GetSelectedFilesWithExtension(".png");

        foreach (var pngFilePath in pngFiles)
        {
            string metaFilePath = pngFilePath + ".meta";

            if (File.Exists(metaFilePath))
            {
                //string metaFileContents = File.ReadAllText(metaFilePath);
                //string assetPath = "Assets" + pngFilePath.Replace(Application.dataPath, "");
                TextureImporter importer = AssetImporter.GetAtPath(pngFilePath) as TextureImporter;

                var setting = importer.GetDefaultPlatformTextureSettings();
                int maxSize = setting.maxTextureSize;
                //Debug.Log("MaxSize: " + maxSize);
                //Debug.Log("Meta file contents:\n" + metaFileContents);
                ScaleAndSaveImage(pngFilePath, pngFilePath, maxSize, maxSize);
            }
            else
            {
                Debug.LogError("Meta file not found for " + pngFilePath);
            }
        }
        //string[] subDirectories = Directory.GetDirectories(dir);

        //foreach (string subDirectory in subDirectories)
        //{
        //    ScalePngFiles(subDirectory);
        //}
    }


    public static void ScaleAndSaveImage(string sourcePath, string outputPath, int newWidth, int newHeight)
    {
        if (!File.Exists(sourcePath))
            return;

        Image sourceImage = Image.FromFile(sourcePath);
        Bitmap scaledImage = new Bitmap(newWidth, newHeight);
        try
        {
            if (sourceImage == null)
                return;

            int sourceWidth = sourceImage.Width;
            int sourceHeight = sourceImage.Height;

            if (newWidth >= sourceImage.Width || sourceWidth <= 256 || sourceWidth != sourceHeight)
            {
                return;
            }

            long oldSize = File.ReadAllBytes(sourcePath).Length;

            // 使用 Graphics 对象进行缩放
            using (System.Drawing.Graphics graphics = System.Drawing.Graphics.FromImage(scaledImage))
            {
                graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
                graphics.DrawImage(sourceImage, 0, 0, newWidth, newHeight);
            }

            sourceImage.Dispose();

            File.Delete(sourcePath);

            scaledImage.Save(outputPath, ImageFormat.Png);

            long newSize = File.ReadAllBytes(outputPath).Length;

            Debug.Log($"scale png width {sourceWidth} to {newWidth} ,from {FormatFileSize(oldSize)} to {FormatFileSize(newSize)}");
        }
        catch (Exception e)
        {
            Debug.LogError(e);
            //sourceImage.Dispose();
        }
        finally
        {
            scaledImage.Dispose();
            sourceImage.Dispose();
        }
    }

    static string FormatFileSize(long bytes)
    {
        string[] suffixes = { "B", "KB", "MB", "GB", "TB", "PB" };
        int suffixIndex = 0;
        double fileSize = bytes;

        while (fileSize >= 1024 && suffixIndex < suffixes.Length - 1)
        {
            fileSize /= 1024;
            suffixIndex++;
        }

        return $"{fileSize:0.##} {suffixes[suffixIndex]}";
    }

    static List<string> GetSelectedFilesWithExtension(params string[] extensions)
    {
        List<string> list = new List<string>();
        UnityEngine.Object[] selectedObjects = Selection.GetFiltered(typeof(object), SelectionMode.DeepAssets);

        foreach (var selectedObject in selectedObjects)
        {
            //Debug.Log($"selectedObject:{selectedObject}");
            string path = AssetDatabase.GetAssetPath(selectedObject);
            if (!string.IsNullOrEmpty(path))
            {
                foreach (var extension in extensions)
                {
                    if (path.EndsWith(extension))
                        list.Add(path);
                }
            }
        }
        return list;
    }
    static List<string> GetSelectedTextureFiles()
    {
        return GetSelectedFilesWithExtension(".jpg",".tga",".png", ".JPG", ".TGA", ".PNG",".exr", ".tif");
    }

    [MenuItem("Tools/Zhan/Optimize textures")]
    public static void OptimizeTextures()
    {
        List<string> list = GetSelectedTextureFiles();

        Debug.Log("OptimizeTextures: " + list.Count);

        foreach (var path in list)
        {
            // 获取纹理的导入器
            TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
            if (importer != null)
            {
                bool changed = false;
                if (importer.isReadable)
                {
                    // 关闭读/写标志
                    importer.isReadable = false;
                    changed = true;
                    Debug.Log("Read/Write flag disabled for " + path);
                }
                if (importer.mipmapEnabled)
                {
                    if(importer.textureCompression == TextureImporterCompression.Uncompressed)
                    {
                        importer.mipmapEnabled = false;
                        changed = true;
                        Debug.Log("mipmap flag disabled for uncompressed tex:" + path);
                    }
                    else if(importer.textureType == TextureImporterType.Sprite)
                    {
                        importer.mipmapEnabled = false;
                        changed = true;
                        Debug.Log("mipmap flag disabled for Sprite tex:" + path);
                    }
                }
                if (importer.filterMode == FilterMode.Trilinear)
                {
                    importer.filterMode = FilterMode.Bilinear;
                    changed = true;
                    Debug.Log("filterMode set from Trilinear to Bilinear for tex:" + path);
                }
                
                if (changed)
                {
                    importer.SaveAndReimport();
                }
            }
        }
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }
    [MenuItem("Tools/Zhan/Set Textures MaxSize 256")]
    public static void SetTexturesMaxSize256()
    {
        List<string> list = GetSelectedTextureFiles();

        Debug.Log("SetTexturesMaxSize256: " + list.Count);
        foreach (var path in list)
        {
            // 获取纹理的导入器
            TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
            if (importer != null)
            {
                if (importer.maxTextureSize ! > 256)
                {
                    importer.maxTextureSize = 256;
                    importer.SaveAndReimport();
                    Debug.Log("set MaxSize 256 for tex:" + path);
                }
            }
        }
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }

    [MenuItem("Tools/Zhan/Disable Textures Mipmap")]
    public static void DisableTexturesMipmap()
    {
        List<string> list = GetSelectedTextureFiles();

        Debug.Log("DisableTexturesMipmap: " + list.Count);

        foreach (var path in list)
        {
            var prefabRoot = AssetDatabase.LoadAssetAtPath<Texture2D>(path);

            // 获取纹理的导入器
            TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
            if (importer != null)
            {
                if (importer.mipmapEnabled)
                {
                    // 关闭读/写标志
                    importer.mipmapEnabled = false;
                    importer.SaveAndReimport();
                    Debug.Log("mipmapEnabled flag disabled for " + path);
                }
            }
        }
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }
    [MenuItem("Tools/Zhan/Disable Textures AlphaSources")]
    public static void DisableTexturesAlphaSources()
    {
        List<string> list = GetSelectedTextureFiles();

        Debug.Log("DisableTexturesMipmap: " + list.Count);

        foreach (var path in list)
        {
            // 获取纹理的导入器
            TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
            if (importer != null)
            {
                if (importer.alphaSource != TextureImporterAlphaSource.None)
                {
                    importer.alphaSource = TextureImporterAlphaSource.None;
                    importer.SaveAndReimport();
                    Debug.Log("Alpha source disable for no alpha tex:" + path);
                }
            }
        }
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }
    [MenuItem("Tools/Zhan/Set Textures Clamp")]
    public static void SetTexturesClamp()
    {
        List<string> list = GetSelectedTextureFiles();

        foreach (var path in list)
        {
            TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
            if (importer != null)
            {
                if (importer.wrapMode !=  TextureWrapMode.Clamp)
                {
                    importer.wrapMode = TextureWrapMode.Clamp;
                    importer.SaveAndReimport();
                    Debug.Log("set wrapMode clamp for tex:" + path);
                }
            }
        }
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }

    // 检查纹理的Alpha通道是否全为0
    private static bool CheckEmptyAlpha(Texture2D texture)
    {
        Color32[] pixels = texture.GetPixels32();

        foreach (Color32 pixel in pixels)
        {
            if (pixel.a != 0 && pixel.a != 255)
            {
                return false;
            }
        }

        return true;
    }

    [MenuItem("Tools/Zhan/Disable Textures Trilinear FilterMode From File")]
    public static void DisableTexturesTrilinearFilterModeFromFile()
    {
        var text = AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/ToDisableTrilinear.txt");
        if (text == null)
        {
            Debug.LogError($"cannot find file");
            return;
        }
        string context = text.text;
        context = context.Replace("\r", "");
        var list = context.Split('\n');

        foreach (var path in list)
        {
            if (path.StartsWith("Height:"))
                continue;

            TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
            if (importer != null)
            {
                if (importer.filterMode ==  FilterMode.Trilinear)
                {
                    importer.filterMode = FilterMode.Bilinear;
                    importer.SaveAndReimport();
                    Debug.Log("set Bilinear for tex:" + path);
                }
            }
        }
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }

    [MenuItem("Tools/Zhan/Disable Textures AlphaSources From File")]
    public static void DisableTexturesAlphaSourcesFromFile()
    {
        var text = AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/ToDisableAlphaSource.txt");
        if(text == null)
        {
            Debug.LogError($"cannot find file");
            return;
        }
        string context = text.text;
        context = context.Replace("\r", "");
        var list = context.Split('\n');

        foreach (var path in list)
        {
            if (path.StartsWith("Height:"))
                continue;

            //Debug.Log($"");
            // 获取纹理的导入器
            TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
            if (importer != null)
            {
                if (importer.alphaSource != TextureImporterAlphaSource.None)
                {
                    importer.alphaSource = TextureImporterAlphaSource.None;
                    importer.SaveAndReimport();
                    Debug.Log("Alpha source disable for no alpha tex:" + path);
                }
            }
        }
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }

    [MenuItem("Tools/Zhan/To Set MaxSize 16 From File")]
    public static void ToSetMaxSize16FromFile()
    {
        var text = AssetDatabase.LoadAssetAtPath<TextAsset>("Assets/ToSetMaxSize32.txt");
        if (text == null)
        {
            Debug.LogError($"cannot find file");
            return;
        }
        string context = text.text;
        context = context.Replace("\r", "");
        var list = context.Split('\n');

        foreach (var path in list)
        {
            if (path.StartsWith("Height:"))
                continue;

            // 获取纹理的导入器
            TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter;
            if (importer != null)
            {
                if (importer.maxTextureSize > 16)
                {
                    importer.maxTextureSize = 16;
                    Debug.Log("To Set MaxSize fo tex:" + path);

                    if (Path.GetExtension(path).ToLower() == ".png")
                    {
                        var setting = importer.GetDefaultPlatformTextureSettings();
                        int maxSize = setting.maxTextureSize;
                        //Debug.Log("MaxSize: " + maxSize);
                        ScaleAndSaveImage(path, path, maxSize, maxSize);
                    }
                }
            }
        }
        AssetDatabase.SaveAssets();
        AssetDatabase.Refresh();
    }
}